home *** CD-ROM | disk | FTP | other *** search
/ Revolution - Das Atari CD Magazin 1997 / Revolution - Das Atari CD Magazin 1.iso / software / anwendng / qed_397 / sourcen / clipbrd.c < prev    next >
C/C++ Source or Header  |  1996-12-29  |  15KB  |  684 lines

  1. #include "global.h"
  2. #include "comm.h"
  3. #include "desktop.h"
  4. #include "edit.h"
  5. #include "file.h"
  6. #include "icon.h"
  7. #include "options.h"
  8. #include "printer.h"
  9. #include "rsc.h"
  10. #include "scroll.h"
  11. #include "set.h"
  12. #include "text.h"
  13. #include "umbruch.h"
  14. #include "windows.h"
  15. #include "clipbrd.h"
  16.  
  17. /* exportierte Variablen ***************************************************/
  18. WORD iclipbrd, clip_type;
  19.  
  20.  
  21. /****** DEFINES ************************************************************/
  22.  
  23. #define KIND    (NAME|CLOSER|FULLER|MOVER|SIZER|UPARROW|DNARROW|VSLIDE|LFARROW|RTARROW|HSLIDE)
  24. #define FLAGS    (WI_TEXT|WI_FONTSIZE)
  25.  
  26. #define MAX_UNDO    5
  27.  
  28. #define END_UNDO    -1
  29.  
  30. /* loake Variablen *********************************************************/
  31. LOCAL TEXTP        clip_text = NULL;
  32. LOCAL BOOLEAN    clip_on_disk;
  33. LOCAL FSEL        fsel;
  34. LOCAL LONG        clip_time = -1;
  35. LOCAL BOOLEAN    clip_dirty, clip_empty;
  36.  
  37. LOCAL WORD    undo[MAX_UNDO];
  38. LOCAL WORD    undo_anz;
  39. LOCAL RING    undo_text;
  40. LOCAL WORD    undo_ptr;
  41.  
  42. /* lokale Prototypen *******************************************************/
  43. LOCAL VOID        set_scrapname    (VOID);
  44. LOCAL VOID        icon_exist        (WORD icon, SET actions);
  45. LOCAL BOOLEAN    icon_test        (WORD icon, WORD action);
  46. LOCAL WORD        icon_edit        (WORD icon, WORD action);
  47. LOCAL BOOLEAN    icon_drag        (WORD icon, WORD source);
  48. LOCAL VOID        crt_clipbrd        (WORD icon, WINDP window);
  49. LOCAL BOOLEAN    open_clipbrd    (WINDP window);
  50. LOCAL VOID        flush_clipbrd    (VOID);
  51. LOCAL VOID        load_clipbrd    (VOID);
  52.  
  53. LOCAL BOOLEAN    scrap_print        (VOID);
  54.  
  55. /***************************************************************************/
  56.  
  57. VOID clr_undo(VOID)
  58. {
  59.     undo_ptr = -1;
  60.     undo_anz = 0;
  61. }
  62.  
  63. BOOLEAN any_undo(VOID)
  64. {
  65.     if (undo_anz && undo[undo_anz-1]==END_UNDO)
  66.         return TRUE;
  67.     return FALSE;
  68. }
  69.  
  70. BOOLEAN test_col_anders(VOID)
  71. {
  72.     WORD i;
  73.  
  74.     if (undo_anz == 0)
  75.         return FALSE;
  76.     if (undo[undo_anz-1] == COL_ANDERS)
  77.         return TRUE;
  78.     if (undo[undo_anz-1] != END_UNDO)
  79.         return FALSE;
  80.     for (i = 0; i < undo_anz; i++)
  81.         if (undo[i]==END_UNDO)
  82.             break;
  83.     if (i > 0 && i < undo_anz)
  84.         return (undo[i-1] == COL_ANDERS);
  85.     return FALSE;
  86. }
  87.  
  88. VOID end_undo_seq(VOID)
  89. {
  90.     WORD    i;
  91.  
  92.     undo_ptr = -1;
  93.     if (undo_anz==0 || undo[undo_anz-1]==END_UNDO)
  94.         return;
  95.     for (i=0; i<undo_anz; i++)
  96.         if (undo[i]==END_UNDO)
  97.         {
  98.             i++;
  99.             undo_anz -= i;
  100.             COPYW(undo, undo+i, (short) sizeof(WORD) * undo_anz);
  101.             break;
  102.         }
  103.     add_undo(END_UNDO);
  104. }
  105.  
  106. VOID add_undo(WORD undo_op)
  107. {
  108.     if (undo_anz<MAX_UNDO && (undo_anz==0 || undo[undo_anz-1]!=undo_op))
  109.         undo[undo_anz++] = undo_op;
  110. }
  111.  
  112. WORD get_undo(VOID)
  113. {
  114.     WORD i;
  115.  
  116.     if (undo_anz==0)
  117.         return NO_UNDO;
  118.     if (undo_ptr<0)
  119.     {
  120.         for (i=0; i<undo_anz; i++)
  121.             if (undo[i]==END_UNDO) break;
  122.         if (i==undo_anz) return NO_UNDO;
  123.         undo_ptr = i;
  124.     }
  125.     undo_ptr--;
  126.     if (undo_ptr<0)
  127.         return NO_UNDO;
  128.     return undo[undo_ptr];
  129. }
  130.  
  131. BOOLEAN clip_ondisk(BOOLEAN flag)
  132. {
  133.     if (flag)
  134.         clip_on_disk = TRUE;
  135.     else
  136.         clip_on_disk = FALSE;
  137.     if (clip_text != NULL)        /* wird vor init. aufgerufen */
  138.     {
  139.         if (scrapdir[0]==EOS)
  140.             clip_on_disk = FALSE;
  141.         set_scrapname();
  142.         load_clipbrd();
  143.     }
  144.     return clip_on_disk;
  145. }
  146.  
  147. BOOLEAN is_clip_ondisk(VOID)
  148. {
  149.     return clip_on_disk;
  150. }
  151.  
  152. LOCAL VOID set_scrapname(VOID)
  153. {
  154.     if (clip_on_disk)
  155.     {
  156.         PATH    str;
  157.  
  158.         strcpy(str, scrapdir);
  159.         strcat(str, "SCRAP.TXT");
  160.         set_text_name(clip_text, str, FALSE);
  161.     }
  162.     else
  163.     {
  164.         CICONBLK    *cicon;
  165.  
  166.         cicon = (CICONBLK *)get_obspec(icons, ICLIP);
  167.         set_text_name(clip_text, cicon->monoblk.ib_ptext, TRUE);
  168.     }
  169. }
  170.  
  171. LOCAL VOID flush_clipbrd(VOID)
  172. {
  173.     BOOLEAN    b;
  174.  
  175.     if (clip_on_disk && clip_dirty)
  176.     {
  177.         set_scrapname();
  178.         b = clip_text->loc_opt->backup;
  179.         clip_text->loc_opt->backup = FALSE;
  180.         clip_text->file_date_time = -1L;        /* damit keine Meldung kommt */
  181.         clip_text->ending = tos;
  182.         scrap_clear();                                /* SCRAP.* löschen */
  183.         save(clip_text);
  184.         send_clip_change();
  185.         clip_text->loc_opt->backup = b;
  186.         clip_time = clip_text->file_date_time;
  187.         clip_dirty = FALSE;
  188.     }
  189. }
  190.  
  191. LOCAL VOID clear_clip(VOID)
  192. {
  193.     clear_text(clip_text);
  194.     clip_text->cursor = FALSE;
  195.     set_scrapname();
  196. }
  197.  
  198.  
  199. LOCAL VOID test_clipbrd(VOID)
  200. {
  201.     if (clip_text!=NULL && clip_empty!=ist_leer(&clip_text->text))
  202.     {
  203.         clip_empty ^= TRUE;
  204.         change_icon_on_desk(iclipbrd,clip_empty?ICLIP:ICLIPFULL);
  205.     }
  206. }
  207.  
  208. LOCAL VOID load_clipbrd(VOID)
  209. {
  210.     LONG    help;
  211.  
  212.     if (!clip_on_disk)
  213.         return;
  214.     if (file_exist(clip_text->filename))
  215.     {
  216.         help = file_time(clip_text->filename,NULL,NULL);
  217.         if (help!=clip_time)                    /* wurde von anderem Programm geändert */
  218.         {
  219.             clip_time = help;
  220.             clear_clip();
  221.             if (load(clip_text, TRUE)!=0)    /* Speichermangel oder Lesefehler */
  222.                 clear_clip();
  223.             make_chg(iclipbrd,TOTAL_CHANGE,0);
  224.             restore_edit();
  225.             test_clipbrd();    /* Icon richtig? */
  226.         }
  227.     }
  228.     else
  229.     {
  230.         clip_time = -1;
  231.         clear_clip();
  232.         make_chg(iclipbrd,TOTAL_CHANGE,0);
  233.         restore_edit();
  234.         test_clipbrd();    /* Icon richtig? */
  235.     }
  236. }
  237.  
  238. /***************************************************************************/
  239. /* Drucken des Clipbrd                                                                        */
  240. /***************************************************************************/
  241.  
  242. LOCAL BOOLEAN scrap_print(VOID)
  243. {
  244.     BOOLEAN ok;
  245.  
  246.     ok = TRUE;
  247.     load_clipbrd();
  248.     if (ist_leer(&clip_text->text))
  249.     {
  250.         note(1,CLIPEMPT);
  251.         ok = FALSE;
  252.     }
  253.     if (ok)
  254.     {
  255.         FILENAME name;
  256.  
  257.         set_scrapname();
  258.         if (clip_on_disk)
  259.             file_name(clip_text->filename, name, FALSE);
  260.         else
  261.             strcpy(name, clip_text->filename);
  262.         if (prn_options(name, FALSE))
  263.             txt_drucken(name, clip_text);
  264.     }
  265.     return(ok);
  266. }
  267.  
  268. /***************************************************************************/
  269. /* Operation vorhanden                                                                        */
  270. /***************************************************************************/
  271.  
  272. LOCAL VOID icon_exist(WORD icon, SET actions)
  273. {
  274.     WINDP    window;
  275.  
  276.     window = get_window(icon);
  277.     setclr(actions);
  278.     setincl(actions,DO_INIT);
  279.     setincl(actions,DO_CLEAR);
  280.     if (window->opened)
  281.         setincl(actions,DO_CLOSE);
  282.     setincl(actions,DO_OPEN);
  283.     setincl(actions,DO_DESTRUCT);
  284.     setincl(actions,DO_INFO);
  285.     setincl(actions,DO_HELP);
  286.     setincl(actions,DO_PRINT);
  287.     setincl(actions,DO_SAVENEW);
  288.     setincl(actions,DO_REINIT);
  289.     setincl(actions,DO_UPDATE);
  290. }
  291.  
  292. /***************************************************************************/
  293. /* Operation testen                                                                            */
  294. /***************************************************************************/
  295.  
  296. LOCAL BOOLEAN icon_test(WORD icon, WORD action)
  297. {
  298.     BOOLEAN    erg;
  299.     WINDP        window;
  300.  
  301.     window = get_window(icon);
  302.     switch(action)
  303.     {
  304.         case DO_CLOSE    :
  305.             erg = window->opened;
  306.             break;
  307.         case DO_INIT    :
  308.         case DO_CLEAR  :
  309.         case DO_OPEN    :
  310.         case DO_DESTRUCT:
  311.         case DO_INFO    :
  312.         case DO_HELP    :
  313.         case DO_PRINT    :
  314.         case DO_SAVENEW:
  315.         case DO_UPDATE :
  316.         case DO_REINIT :
  317.             erg = TRUE;
  318.             break;
  319.         default            :
  320.             erg = FALSE;
  321.     }
  322.     return erg;
  323. }
  324.  
  325. /***************************************************************************/
  326. /* Operation durchführen                                                                    */
  327. /***************************************************************************/
  328.  
  329. LOCAL WORD icon_edit(WORD icon, WORD action)
  330. {
  331.     WORD        erg = 1;
  332.     WINDOWP    window;
  333.     PATH        name;
  334.  
  335.     window = get_window(icon);
  336.     switch(action)
  337.     {
  338.         case DO_INIT    :
  339.             clip_text = new_text(icon);
  340.             create_window(KIND,CLASS_CLIP,icon,crt_clipbrd);
  341.             load_clipbrd();
  342.             break;
  343.         case DO_CLEAR  :
  344.             clear_clip();
  345.             if (clip_on_disk)
  346.                 scrap_clear();
  347.             make_chg(icon,TOTAL_CHANGE,0);
  348.             restore_edit();
  349.             break;
  350.         case DO_CLOSE    :
  351.             close_window(window);
  352.             break;
  353.         case DO_DESTRUCT:
  354.             destruct_window(window);
  355.             destruct_text(clip_text);
  356.             clip_text = NULL;
  357.             clip_time = -1;
  358.             kill_textring(&undo_text);
  359.             break;
  360.         case DO_OPEN    :
  361.             if (!open_clipbrd (window))
  362.                 erg = -1;
  363.             break;
  364.         case DO_INFO    :
  365.             load_clipbrd();
  366.             info_edit(icon);
  367.             break;
  368.         case DO_HELP    :
  369.             note (1, HELPCLIP);
  370.             break;
  371.         case DO_PRINT  :
  372.             scrap_print();
  373.             break;
  374.         case DO_SAVENEW:
  375.             load_clipbrd();
  376.             if (ist_leer(&clip_text->text))
  377.             {
  378.                 note(1,CLIPEMPT);
  379.                 erg = -1;
  380.             }
  381.             else
  382.             {
  383.                 if (save_new(name, &fsel, STRING(SAVECLIPSTR)))
  384.                 {
  385.                     erg = save_as(clip_text,name);
  386.                     if (erg==0) erg = 1;
  387.                 }
  388.             }
  389.             break;
  390.         case DO_REINIT :
  391.             clip_text = new_text(icon);
  392.             init_textring(&undo_text);
  393.             create_window(KIND,CLASS_CLIP,icon,crt_clipbrd);
  394.             load_clipbrd();
  395.             break;
  396.         case DO_UPDATE :
  397.             flush_clipbrd();
  398.             load_clipbrd();
  399.             break;
  400.     }
  401.     test_clipbrd();    /* Icon richtig? */
  402.     return erg;
  403. }
  404.  
  405. /***************************************************************************/
  406. /* Reaktion des Verschiebens auf das CLIPBRD-Icon                                    */
  407. /***************************************************************************/
  408.  
  409. LOCAL BOOLEAN icon_drag (WORD icon, WORD source)
  410. {
  411.     RING    t;
  412.     TEXTP t_ptr = get_text(source);
  413.  
  414.     if (t_ptr!=NULL)
  415.     {
  416.         init_textring(&t);
  417.         if (!doppeln(&t_ptr->text,&t))
  418.         {
  419.             kill_textring(&t);
  420.             return FALSE;
  421.         }
  422.         if (global_shift)
  423.             clip_add_text(&t);
  424.         else
  425.             clip_takes_text(&t);
  426.         restore_edit();
  427.         return TRUE;
  428.     }
  429.     return FALSE;
  430. }
  431.  
  432. /***************************************************************************/
  433.  
  434. VOID undo_takes_text(RINGP r)
  435. {
  436.     kill_textring(&undo_text);
  437.     undo_text = *r;
  438.     FIRST(r)->vorg = &undo_text.head;
  439.     LAST(r)->nachf = &undo_text.tail;
  440. }
  441.  
  442. RINGP get_undo_text(VOID)
  443. {
  444.     return &undo_text;
  445. }
  446.  
  447. /***************************************************************************/
  448.  
  449. VOID clip_takes_text(RINGP r)
  450. {
  451.     TEXTP t_ptr = clip_text;
  452.  
  453.     kill_textring(&t_ptr->text);
  454.     t_ptr->text = *r;
  455.     FIRST(r)->vorg = &t_ptr->text.head;
  456.     LAST(r)->nachf = &t_ptr->text.tail;
  457.     t_ptr->cursor_line = FIRST(&t_ptr->text);
  458.     make_chg(iclipbrd,TOTAL_CHANGE,0);
  459.     clip_dirty = TRUE;
  460.     test_clipbrd();    /* Icon richtig? */
  461. }
  462.  
  463. VOID clip_add_text(RINGP r)
  464. {
  465.     TEXTP t_ptr = clip_text;
  466.     LINEP    col;
  467.  
  468.     col = LAST(&t_ptr->text);            /* letzte Zeile */
  469.     col->nachf = FIRST(r);
  470.     FIRST(r)->vorg = col;
  471.     LAST(r)->nachf = &t_ptr->text.tail;
  472.     LAST(&t_ptr->text) = LAST(r);
  473.     t_ptr->text.lines += r->lines;
  474.     col_concate(&col);
  475.     t_ptr->text.lines--;
  476.     make_chg(iclipbrd, TOTAL_CHANGE, 0);
  477.     clip_dirty = TRUE;
  478.     test_clipbrd();    /* Icon richtig? */
  479. }
  480.  
  481. /***************************************************************************/
  482.  
  483. LOCAL BOOLEAN wi_key(WINDOWP window, MKINFO *mk)
  484. {
  485.     BOOLEAN    erg;
  486.     WORD        key_code;
  487.  
  488.     erg = FALSE;
  489.     if (mk->kreturn & NKF_FUNC)
  490.     {
  491.         if (mk->kreturn & NKF_SHIFT)                            /* alle Shift-Codes */
  492.         {
  493.             key_code = mk->kreturn & ~(NKF_FUNC|NKF_SHIFT);
  494.             switch (key_code)
  495.             {
  496.                 case NK_CLRHOME:
  497.                     v_slider(window,1000);
  498.                     erg = TRUE;
  499.                     break;
  500.                 case NK_UP:
  501.                     arrow_window(window, WA_UPPAGE, 1);
  502.                     erg = TRUE;
  503.                     break;
  504.                 case NK_DOWN:
  505.                     arrow_window(window, WA_DNPAGE, 1);
  506.                     erg = TRUE;
  507.                     break;
  508.                 case NK_LEFT:
  509.                     arrow_window(window, WA_LFPAGE, 1);
  510.                     erg = TRUE;
  511.                     break;
  512.                 case NK_RIGHT:
  513.                     arrow_window(window, WA_RTPAGE, 1);
  514.                     erg = TRUE;
  515.                     break;
  516.                 default:
  517.                     erg = FALSE;
  518.             }
  519.         }
  520.         else
  521.         {
  522.             key_code = mk->kreturn & ~NKF_FUNC;;
  523.             switch (key_code)
  524.             {
  525.                 case NK_CLRHOME :
  526.                     v_slider(window, 0);
  527.                     erg = TRUE;
  528.                     break;
  529.                 case NK_UP:
  530.                     arrow_window(window, WA_UPLINE, 1);
  531.                     erg = TRUE;
  532.                     break;
  533.                 case NK_DOWN :
  534.                     arrow_window(window, WA_DNLINE, 1);
  535.                     erg = TRUE;
  536.                     break;
  537.                 case NK_LEFT :
  538.                     arrow_window(window, WA_LFLINE, 1);
  539.                     erg = TRUE;
  540.                     break;
  541.                 case NK_RIGHT:
  542.                     arrow_window(window, WA_RTLINE, 1);
  543.                     erg = TRUE;
  544.                     break;
  545.                 case NK_M_PGUP:                /* Mac: page up -> shift-up */
  546.                     arrow_window(window, WA_UPPAGE, 1);
  547.                     erg = TRUE;
  548.                     break;
  549.                 case NK_M_PGDOWN:                /* Mac: page down -> shift-down */
  550.                     arrow_window(window, WA_DNPAGE, 1);
  551.                     erg = TRUE;
  552.                     break;
  553.                 case NK_M_END:                    /* Mac: end -> shift-home */
  554.                     v_slider(window,1000);
  555.                     erg = TRUE;
  556.                     break;
  557.                 default:
  558.                     erg = FALSE;
  559.             }
  560.         }
  561.     }
  562.     else
  563.         erg = FALSE;
  564.     return (erg);
  565. }
  566.  
  567. /***************************************************************************/
  568. /* Kreieren eines Fensters                                                                    */
  569. /***************************************************************************/
  570.  
  571. LOCAL VOID crt_clipbrd (WORD icon, WINDOWP window)
  572. {
  573.     WORD        initw, inith;
  574.     CICONBLK *cicon;
  575.  
  576.     clip_text->cursor = FALSE;
  577.     clip_text->ending = tos;
  578.  
  579.     set_scrapname();
  580.  
  581.     initw  = min (desk.w / gl_wchar * gl_wchar - 7 * gl_wchar, 80 * gl_wchar);
  582.     inith  = (desk.h / gl_hchar) * gl_wchar - 7 * gl_hchar;
  583.  
  584.     window->flags        = FLAGS;
  585.     window->doc.w        = MAX_LINE_LEN;
  586.     window->doc.h        = clip_text->text.lines;
  587.     window->xfac        = gl_wchar;
  588.     window->yfac        = gl_hchar;
  589.     window->w_width    = initw/gl_wchar;
  590.     window->w_hight    = inith/gl_hchar;
  591.     window->work.x        = sys_wchar;
  592.     window->work.y        = 42;
  593.     window->work.w        = initw;
  594.     window->work.h        = inith;
  595.     window->draw        = wi_draw_edit;    /* gleiche Routinen wie für EDIT */
  596.     window->key            = wi_key;
  597.  
  598.     cicon = (CICONBLK *)get_obspec(icons, ICLIP);
  599.     set_wname(window, cicon->monoblk.ib_ptext);
  600. } /* crt_clipbrd */
  601.  
  602. /***************************************************************************/
  603. /* Öffnen des Objekts                                                                        */
  604. /***************************************************************************/
  605.  
  606. LOCAL BOOLEAN open_clipbrd (WINDOWP window)
  607. {
  608.     BOOLEAN    ok;
  609.  
  610.     if (window->opened)
  611.     /* Doppelklick auf Icon und Fenster ist schon offen */
  612.     {
  613.         top_window (window);
  614.         ok = TRUE;
  615.     }
  616.     else
  617.     {
  618.         load_clipbrd();
  619.         ok = open_window(window);
  620.     }
  621.     return (ok);
  622. } /* open_clipbrd */
  623.  
  624. /***************************************************************************/
  625.  
  626. VOID init_clipbrd(VOID)
  627. {
  628.     PATH        s;
  629.     UBYTE        *str;
  630.     CICONBLK *cicon;
  631.  
  632.     scrp_read (scrapdir);                            /* Scrap-Directory lesen */
  633.     if (scrapdir[0] == EOS)                            /* Noch keines gesetzt */
  634.     {
  635.         if ((str=getenv("SCRAPDIR"))!=NULL && *str!=EOS)
  636.             strcpy(scrapdir, str);
  637.  
  638.         else if ((str=getenv("CLIPBRD"))!=NULL && *str!=EOS)
  639.             strcpy(scrapdir, str);
  640.  
  641.         else
  642.         {
  643.             WORD drive;
  644.  
  645.             strcpy (scrapdir, "A:\\CLIPBRD\\");
  646.             drive = get_first_drive();
  647.             if (drive > 0)
  648.                 scrapdir[0] = 'A' + (UBYTE) drive;
  649.         }
  650.         scrp_write (scrapdir);                        /* Scrap-Directory setzen */
  651.     }
  652.     make_normalpath(scrapdir,FALSE);
  653.     if (!path_exist (scrapdir))
  654.     {
  655.         if (scrapdir[0]=='A' || scrapdir[0]=='B' ||
  656.             scrapdir[0]=='a' || scrapdir[0]=='b')
  657.             scrapdir[0] = EOS;                        /* Kein Klemmbrett auf Disketten! */
  658.         else
  659.         {
  660.             strcpy (s, scrapdir);
  661.             s[strlen(s)-1] = EOS;                    /* Backslash löschen */
  662.             if (Dcreate(s)!=0)
  663.             {
  664.                 note(1, NOSCRAP);
  665.                 scrapdir[0] = EOS;                    /* Kein Klemmbrett */
  666.             }
  667.         }
  668.     }
  669.     if (scrapdir[0]==EOS)
  670.         clip_on_disk = FALSE;
  671.  
  672.     strcpy(fsel.suffix,"*.*");
  673.     fsel.name[0] = EOS;
  674.     init_textring(&undo_text);
  675.     clr_undo();
  676.     clip_empty = TRUE;
  677.     clip_dirty = FALSE;
  678.     clip_type = decl_icon_type(icon_test, icon_edit, icon_exist, icon_drag);
  679.  
  680.     cicon = (CICONBLK *)get_obspec(icons, ICLIP);
  681.     iclipbrd = add_icon_to_desk(ICLIP, cicon->monoblk.ib_ptext, -1, -1);
  682.     add_icon(clip_type,iclipbrd);
  683. }
  684.